<!-- 进程管控 -->
<template>
  <div>
    <el-row>
      <div style="display:flex;padding: 15px 0;">
        <div style="min-width:160px;color:#606266;font-size:14px;">进程审计工作模式：</div>
        <div>
          <el-radio v-model="AuditMode" :label="1" @change="radioChange"
            style="width:100%;margin-bottom:10px;">不启用进程审计功能模块</el-radio>
          <el-radio v-model="AuditMode" :label="2" @change="radioChange"
            style="width:100%;margin-bottom:10px;">学习模式(只上送日志，不阻断，常见为实施部署初始阶段)</el-radio>
          <el-radio v-model="AuditMode" :label="3" @change="radioChange"
            style="width:100%;margin-bottom:10px;">策略阻断模式，根据如下策略进行进程阻断，未知进程能够正常运行（同时上送文件到设备检测）</el-radio>
          <el-radio v-model="AuditMode" :label="4" @change="radioChange"
            style="width:100%;margin-bottom:10px;">策略阻断加延迟审核模式，根据如下策略进行进程阻断，未知进程需要在设备上校验没有病毒后才能够正常运行</el-radio>
        </div>
      </div>
      <div style="display:flex;justify-content:space-between;">
        <div>
          <el-button type="primary" icon='el-icon-circle-plus-outline' @click="addClick()">添加规则</el-button>
          <span style="color:#d2d7e3;font-size:25px;margin-top:10px;padding-left:10px;">
            <el-tooltip class="item" effect="dark" placement="right">
              <i class="el-icon-question"></i>
              <div style="width: 420px;" slot="content">通过拖动表格行来重新排列顺序, 系统按次序从上到下优先级执行。添加放到所有规则最后，插入表示在当前策略前插入一条规则。</div>
            </el-tooltip>
          </span>
        </div>
      </div>
      <el-table stripe border :data="tableData" class="draggable-table" table-id="table1" row-key="RuleName"
        style="width: 100%; margin-top: 15px">
        <el-table-column label="序号" width="60" type="index"
          :index='(index) => { return (index + 1) + (this.pageNum - 1) * this.pageSize }'> </el-table-column>
        <el-table-column label="规则名称" prop="RuleName"  show-overflow-tooltip width="160px"></el-table-column>
        <el-table-column label="规则状态" show-overflow-tooltip prop="IsValid"  width="160px">
          <template slot-scope="{row}">
            <span style="color:#67C23A" v-if="row.IsValid === 1" type="success">正常</span>
            <span style="color:#F56C6C" v-else type="danger">失效</span>
          </template>
        </el-table-column>
        <el-table-column label="应用对象类型" show-overflow-tooltip prop="DeviceObjType" width="120px">
          <template slot-scope="{row}">
            <span>{{ DeviceObjTypeFormatter(row) }}</span>
          </template>
        </el-table-column>
        <el-table-column label="应用对象" show-overflow-tooltip prop="DeviceObj" width="160px">
          <template slot-scope="{row}">
            <span>{{ getDeviceObjDisplay(row, DepartmentList, AssetsList) }}</span>
          </template>
        </el-table-column>
        <!-- <el-table-column label="默认策略" show-overflow-tooltip prop="DefaultPolicy"  width="120px">
        <template slot-scope="{row}">
          <span>{{ row.DefaultPolicy === 1 ? '默认策略' : '自定义策略'}}</span>
        </template>
      </el-table-column>  -->
        <el-table-column label="策略数量" show-overflow-tooltip prop="ProcObjs" width="100px" >
          <template slot-scope="{row}">
            <span>{{ row.ProcObjs ? row.ProcObjs.length : 0 }}</span>
          </template>
        </el-table-column>
        <el-table-column label="备注信息" show-overflow-tooltip prop="Descp" ></el-table-column>
        <el-table-column label="操作" fixed="right" width="220px">
          <template slot-scope="scope">
            <el-button size="mini" type="success" @click="insertClick(scope.row, scope.$index)">插入</el-button>
            <el-button size="mini" type="primary" @click="changeClick(scope.row, scope.$index)">修改</el-button>
            <el-button size="mini" type="danger" @click="deleteClick(tableData, scope.$index)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-row>
    <el-dialog top="5vh" :close-on-click-modal="false" :close-on-press-escape=false
      :title="Action === 1 ? '添加规则'  : Action === 2 ? '修改规则' : '插入规则'" :visible.sync="dialogVisible" @close="getData()" v-el-drag-dialog
      width="1000px">
      <el-form label-width="130px" :model="accountForm" :rules="rules" ref="accountForm" class="ruleDialogForm">
        <el-row class="ruleMain">
          <el-divider content-position="left">基本规则内容</el-divider>
          <el-col :xs="24" :sm="24" :lg="24">
            <el-form-item label='规则名称：' prop="RuleName">
              <el-input v-model.trim="accountForm.RuleName" :disabled="Action === 2" :maxlength="30"></el-input>
            </el-form-item>
            <el-form-item label='规则状态：' prop="IsValid">
              <el-radio v-model="accountForm.IsValid" :label="1">正常</el-radio>
              <el-radio v-model="accountForm.IsValid" :label="0">失效</el-radio>
            </el-form-item>
            <device-object-selector :form.sync="accountForm" />
            <el-form-item label="备注信息：" prop="Descp">
              <el-input placeholder="请输入备注" type="textarea" maxlength="50" :rows="3" v-model="accountForm.Descp"></el-input>
            </el-form-item>
            <el-form-item label="审计对象：" prop="Descp">
              <el-button @click="addAuditObj" type="primary" size="mini">添加审计对象</el-button>
              <span style="color:#d2d7e3;font-size:25px;margin-top:10px;padding-left:10px;">
                <el-tooltip class="item" effect="dark" content="``" placement="right">
                  <i class="el-icon-question"></i>
                  <div style="width: 420px;" slot="content">通过拖动表格行来重新排列顺序, 系统按次序从上到下优先级执行，找到规则后将不会执行后续规则。</div>
                </el-tooltip>
              </span>
              <el-row>
                <el-table stripe border :data="accountForm.ProcObjs" class="draggable-table" table-id="table2"
                  row-key="index" height="320" style="width: 100%; margin-top: 5px;">
                  <el-table-column label="序号" width="60" type="index"
                    :index='(index) => { return (index + 1) + (this.pageNum - 1) * this.pageSize }'> </el-table-column>
                  <el-table-column label="控制策略" prop="Policy"  show-overflow-tooltip>
                    <template slot-scope="{row}">
                      <span>{{ row.Policy === 1 ? '白名单' : '黑名单' }}</span>
                    </template>
                  </el-table-column>
                  <el-table-column label="控制类型" show-overflow-tooltip prop="Type" >
                    <template slot-scope="{row}">
                      <span>{{ row.Type === 1 ? '进程名称' : '进程Hash' }}</span>
                    </template>
                  </el-table-column>
                  <el-table-column label="控制对象" show-overflow-tooltip prop="Obj" ></el-table-column>
                  <el-table-column label="操作" width="220px">
                    <template slot-scope="scope">
                      <el-button size="mini" type="primary" @click="AuditinsertClick(scope.$index)">插入</el-button>
                      <el-button size="mini" type="primary"
                        @click="AuditchangeClick(scope.row, scope.$index)">修改</el-button>
                      <el-button size="mini" type="danger"
                        @click="AuditdeleteClick(accountForm.ProcObjs, scope.$index)">删除</el-button>
                    </template>
                  </el-table-column>
                </el-table>
              </el-row>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <el-divider></el-divider>
      <span slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submit()">确 定</el-button>
        <el-button type="info" @click="dialogVisible = false; getData()">取 消</el-button>
      </span>
    </el-dialog>
    <el-dialog :close-on-click-modal="false" :close-on-press-escape=false
      :title="auditAction === 1 ? '添加审计对象' : '修改审计对象'" :visible.sync="auditdialog" v-el-drag-dialog width="600px">
      <el-form label-width="130px" :model="auditForm" :rules="rules2" ref="auditForm">
        <el-row>
          <el-col :xs="24" :sm="24" :lg="24">
            <el-form-item label='控制策略：' prop="Policy">
              <el-radio v-model="auditForm.Policy" :label="1">白名单</el-radio>
              <el-radio v-model="auditForm.Policy" :label="2">黑名单</el-radio>
            </el-form-item>
            <el-form-item label='规则状态：' prop="Type">
              <el-radio v-model="auditForm.Type" :label="1">名称</el-radio>
              <el-radio v-model="auditForm.Type" :label="2">Hash</el-radio>
            </el-form-item>
            <el-form-item label='控制对象：' prop="Obj">
              <el-select style="width:100%" v-model="auditForm.Obj" placeholder="请选择控制对象" filterable allow-create
                :default-first-option="true" @blur="selectBlur($event)">
                <el-option v-for="(item, index) in OBJList" :key="index" :label="item.Name"
                  :value="auditForm.Type === 1 ? item.Name : item.Hash"></el-option>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button type="primary" @click="auditsubmit()">确 定</el-button>
        <el-button type="info" @click="auditdialog = false">取 消</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import { connrequest } from '@/api/firstPage'
import { getDeviceObjDisplay, DeviceObjTypeFormatter } from '@/utils/index.js';
import elDragDialog from '@/directive/el-drag-dialog' // base on element-ui
import Sortable from "sortablejs";
import DeviceObjectSelector from '@/components/DeviceObjectSelector'
export default {
  directives: { elDragDialog },
  components: {
    DeviceObjectSelector
  },
  data() {
    return {
      pageNum: 1,
      pageSize: 10,
      tableData: [],
      AuditMode: 1,
      RoleList: [],
      DepartmentList: [],
      AssetsList: [],
      DeviceObjList: [],
      Action: 0,
      dialogVisible: false,
      accountForm: {},
      auditAction: 1,
      auditdialog: false,
      auditForm: {
        Policy: 1,
        Type: 1,
        Obj: ''
      },
      OBJList: '',
      rules: {
        RuleName: [
          { required: true, message: "请输入规则名称" }
        ],
      },
      rules2: {
        Policy: [
          { required: true, message: "请选择控制策略", trigger: 'change' }
        ],
        Type: [
          { required: true, message: "请选择规则状态", trigger: 'change' }
        ],
        Obj: [
          { required: true, message: "请选择控制对象", trigger: 'change' }
        ],
      }
    }
  },
  watch: {
    Action() {
      this.$nextTick(() => {
        this.initSort()
      })
    }
  },
  //生命周期 - 创建完成（访问当前this实例）
  created() {
    this.GetDepartment()
    this.GetDevice()
    this.getData()
  },
  //生命周期 - 挂载完成（访问DOM元素）
  mounted() {
    this.initSort();
  },
  methods: {
    DeviceObjTypeFormatter,
    getDeviceObjDisplay,
    // 获取所有部门
    async GetDepartment() {
      const res = await connrequest('GetDepartment')
      this.DepartmentList = res.Data
    },
    // 获取所有资产
    async GetDevice() {
      const data = {
        Paging: {
          QueryPageNo: 1,
          QueryPageLength: 100000
        },
      }
      const res = await connrequest('GetDevice', data)
      this.AssetsList = res.Data
    },
    initSort() {
      document.querySelectorAll('.draggable-table').forEach(table => {
        const el = table.querySelector('.el-table__body-wrapper > table > tbody');
        const tableId = table.getAttribute('table-id');
        new Sortable(el, {
          animation: 500,
          onEnd: async (evt) => {
            if (tableId === 'table1') {
              const currRow = this.tableData.splice(evt.oldIndex, 1)[0];
              this.tableData.splice(evt.newIndex, 0, currRow);
              const newData = [];
              this.tableData.forEach((item, index) => {
                newData[index] = {
                  id: item.id,
                  rank: index + 1
                };
              });
              const data = {
                Filter: {
                  FileName: 'rule_proc.json'
                },
                Data: {
                  AuditMode: this.AuditMode,
                  RuleData: [...this.tableData]
                }
              };
              const res = await connrequest('SetUICommonParam', data);
              if (res.Status.StatusCode === 0) {
                this.$message.success('排序成功');
                this.getData();
              }
            }
            if (tableId === 'table2') {
              const listTemp = [...this.accountForm.ProcObjs];
              const oldValue = listTemp.splice(evt.oldIndex, 1); // 取出旧值
              listTemp.splice(evt.newIndex, 0, oldValue[0]); // 添加到新位置
              this.accountForm.ProcObjs = []; // 1.清空(这样ABC才会重新渲染)
              this.$nextTick(() => {
                this.accountForm.ProcObjs = listTemp; // 2.重新赋值(这样ABC才会重新渲染)
              });
            }
          }
        });
      });
    },
    selectBlur(e) {
      if (e.target.value) {
        this.$set(this.auditForm, 'Obj', e.target.value);
      }
    },
    async GetDictProcess() {
      const res = await connrequest('GetDictProcess')
      this.OBJList = res.Data
    },
    async getData() {
      const data = {
        Filter: {
          FileName: 'rule_proc.json'
        }
      }
      const res = await connrequest('GetUICommonParam', data)
      this.AuditMode = res.Data.AuditMode
      this.tableData = res.Data?.RuleData || []
    },
    addClick() {
      this.Action = 1;
      this.$nextTick(() => {
        // 等待组件挂载
        this.accountForm = {
          IsValid: 1,
          DeviceObjType: 1,
          DeviceObj: [],
          ProcObjs: []
        };
        this.$refs['accountForm'].resetFields();
      });
      this.dialogVisible = true;
    },
    insertClick(row, index) {
      this.Action = 3
      this.tableindex = index
      this.$nextTick(() => {
        // 等待组件挂载
        this.accountForm = {
          IsValid: 1,
          DeviceObjType: 1,
          DeviceObj: [],
          ProcObjs: []
        };
        this.$refs['accountForm'].resetFields();
      });
      this.dialogVisible = true;
    },
    changeClick(row, index) {
      this.tableindex = index
      this.Action = 2
      this.$nextTick(() => {
        this.accountForm = { ...row, ProcObjs: row.ProcObjs }
        this.$refs['accountForm'].resetFields();
      })
      this.dialogVisible = true
    },
    deleteClick(tableData, index) {
      this.$confirm('此操作将永久删除该规则, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(async () => {
        tableData.splice(index, 1)
        const data = {
          Filter: {
            FileName: 'rule_proc.json'
          },
          Data: {
            AuditMode: this.AuditMode,
            RuleData: [
              ...tableData
            ]
          }
        }
        const res = await connrequest('SetUICommonParam', data)
        if (res.Status.StatusCode === 0) {
          this.$message({
            type: 'success',
            message: '删除成功!'
          });
          this.getData()
        }
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        });
      });
    },
    submit() {
      this.$refs['accountForm'].validate(async (valid) => {
        if (valid) {
          if (this.accountForm.DeviceObjType === 2) {
            if (!this.accountForm.DeviceObj || this.accountForm?.DeviceObj?.length === 0) {
              this.$message.error('请选择部门')
              return false
            }
          }
          if (this.accountForm.DeviceObjType === 8) {
            if (!this.accountForm.DeviceObj || this.accountForm?.DeviceObj?.length === 0) {
              this.$message.error('请选择角色')
              return false
            }
          }
          if (this.accountForm.DeviceObjType === 6) {
            if (!this.accountForm.DeviceObj || this.accountForm?.DeviceObj?.length === 0) {
              this.$message.error('请选择资产')
              return false
            }
          }
          if (this.accountForm.ProcObjs.length === 0) {
            this.$message.error('审计对象不能为空')
            return false
          }
          if (this.Action !== 2 && this.tableData.findIndex(item => item.RuleName === this.accountForm.RuleName) !== -1) {
            this.$message.error('该规则已经存在')
            return false
          }
          let data = {}
          if (this.Action === 1) {
            data = {
              Filter: {
                FileName: 'rule_proc.json'
              },
              Data: {
                AuditMode: this.AuditMode,
                RuleData: [
                  ...this.tableData,
                  {
                    ...this.accountForm,
                    RuleID: Math.floor(Date.now() / 1000)
                  }
                ]
              }
            }
          }
          if (this.Action === 2) {
            this.tableData[this.tableindex] = this.accountForm
            data = {
              Filter: {
                FileName: 'rule_proc.json'
              },
              Data: {
                AuditMode: this.AuditMode,
                RuleData: [
                  ...this.tableData
                ]
              }
            }
          }
          if (this.Action === 3) {
            this.tableData.splice(this.tableindex + 1, 0, { ...this.accountForm, RuleID: Math.floor(Date.now() / 1000) })
            data = {
              Filter: {
                FileName: 'rule_proc.json'
              },
              Data: {
                AuditMode: this.AuditMode,
                RuleData: [
                  ...this.tableData
                ]
              }
            }
          }
          const res = await connrequest('SetUICommonParam', data)
          if (res.Status.StatusCode === 0) {
            this.$message.success(this.Action == 1 ? '添加成功' : '修改成功')
            this.getData()
            this.dialogVisible = false
          }
        }
      })
    },
    async radioChange(row) {
      const data = {
        Filter: {
          FileName: 'rule_proc.json'
        },
        Data: {
          AuditMode: row,
          RuleData: this.tableData
        }
      }
      const res = await connrequest('SetUICommonParam', data)
      if (res.Status.StatusCode === 0) {
        this.$message.success('修改成功')
        this.getData()
      }
    },
    addAuditObj() {
      this.auditAction = 1
      this.auditForm = {
        Policy: 1,
        Type: 1,
        Obj: ''
      }
      this.GetDictProcess()
      this.auditdialog = true
      this.$nextTick(() => {
        this.$refs['auditForm'].resetFields()
      })
    },
    AuditchangeClick(row, index) {
      this.auditAction = 2
      this.AuditIndex = index
      this.auditForm = { ...row }
      this.GetDictProcess()
      this.auditdialog = true
    },
    AuditinsertClick(index) {
      this.auditAction = 3
      this.AuditIndex = index
      this.auditForm = {
        Policy: 1,
        Type: 1,
        Obj: ''
      }
      this.GetDictProcess()
      this.auditdialog = true
      this.$nextTick(() => {
        this.$refs['auditForm'].resetFields()
      })
    },
    AuditdeleteClick(tableData, index) {
      tableData.splice(index, 1)
    },
    auditsubmit() {
      this.$refs['auditForm'].validate(async (valid) => {
        if (valid) {
          if (this.auditAction === 1) {
            this.accountForm.ProcObjs.push(this.auditForm)
          }
          if (this.auditAction === 2) {
            this.$set(this.accountForm.ProcObjs, this.AuditIndex, this.auditForm);
          }
          if (this.auditAction === 3) {
            this.accountForm.ProcObjs.splice(this.AuditIndex, 0, this.auditForm)
          }
          this.auditdialog = false
        }
      })
    }
  }
}
</script>